package com.googlecode.lohr.tools.interpreter;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class ObjectImpl {
	
	final private String _uri;
	final private LohrInterpreter _interpreter;
	final private TypeImpl _type;
	private PackageImpl _package;
	final private Map<String, ObjectImpl> _values= new HashMap<String, ObjectImpl>(); 

	/**
	 * Creates an object with the given URI 
	 */
	public ObjectImpl(LohrInterpreter interpreter, TypeImpl type, String uri) {
		_interpreter= interpreter;
		_type= type;
		_uri= uri;
	}
	/**
	 * Creates an object with a random URI 
	 */
	public ObjectImpl(LohrInterpreter interpreter, TypeImpl type) {
		this (interpreter, type, UUID.randomUUID().toString());
	}
	
	/**
	 * Every lohr object has an associated package to which the object belongs
	 */
	public PackageImpl getPackageImpl() {
		if (_package == null) {
			String packageName= _uri;
			if (packageName.contains(".")) 
				packageName= packageName.substring(0, packageName.lastIndexOf("."));
			_package= _interpreter._respository.findByURI(packageName);
		}
		return _package;
	}
	/**
	 * Every lohr object has a URI
	 */
	public String getURI() {
		return _uri;
	}
	/**
	 * Every lohr object has an associated type
	 */
	public TypeImpl getType() {
		return _type;
	}
	public LohrInterpreter getInterpreter() {
		return _interpreter;
	}
	

	/*
	 * Every object has the ability to be invoked like a method.
	 * Of course, not every object will support this operation.
	 */
	public ObjectImpl invoke(ObjectImpl invocationContext, Locals arguments) {
		throw new RuntimeException("This object may not be invoked");
	}
	
	public void createSlot(AccessType accessType, String slotName, ObjectImpl slotValue) {
		_values.put(slotName, slotValue);
		if (AccessType.PUBLIC.equals(accessType))
			_interpreter.getRespository().register(slotValue);
	}
}
